package com.lancer.cloud.common.util;

import com.lancer.cloud.common.constants.CharacterConstants;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;

/**
 * IP工具类
 *
 * @author caijinbang
 * @date 2019-06-16 09:56
 */
public class IpUtils {

    /**
     * 未知
     */
    public static final String UNKNOW = "unknown";

    /**
     * 扩展头,用来表示 HTTP 请求端真实 IP
     */
    public static final String X_FORWARDED_FOR = "x-forwarded-for";

    /**
     * 代理服务器请求头,用apache http做代理时一般会加上Proxy-Client-IP请求头
     */
    public static final String PROXY_CLIENT_IP = "Proxy-Client-IP";

    /**
     * WL- Proxy-Client-IP是PROXY_CLIENT_IP的WebLogic插件加上的头
     */
    public static final String WL_PROXY_CLIENT_IP = "WL-Proxy-Client-IP";

    /**
     * 获取目标主机的IP
     *
     * @param request 网络请求
     * @return IP Address
     */
    public static String getIpAddrByRequest(HttpServletRequest request) {
        String ip = request.getHeader(X_FORWARDED_FOR);
        if (ip == null || ip.length() == 0 || UNKNOW.equalsIgnoreCase(ip)) {
            ip = request.getHeader(PROXY_CLIENT_IP);
        }
        if (ip == null || ip.length() == 0 || UNKNOW.equalsIgnoreCase(ip)) {
            ip = request.getHeader(WL_PROXY_CLIENT_IP);
        }
        if (ip == null || ip.length() == 0 || UNKNOW.equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }


    /**
     * @return 获取本机IP
     */
    public static String getRealIp() throws SocketException {
        // 本地IP，如果没有配置外网IP则返回它
        String localIp = null;
        // 外网IP
        String netIp = null;
        Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
        InetAddress ip = null;
        // 是否找到外网IP
        boolean find = false;
        while (netInterfaces.hasMoreElements() && !find) {
            NetworkInterface ni = netInterfaces.nextElement();
            Enumeration<InetAddress> address = ni.getInetAddresses();
            while (address.hasMoreElements()) {
                ip = address.nextElement();
                // 外网IP
                if (!ip.isSiteLocalAddress()
                    && !ip.isLoopbackAddress()
                    && !ip.getHostAddress().contains(CharacterConstants.COLON)) {
                    netIp = ip.getHostAddress();
                    find = true;
                    break;
                } else if (ip.isSiteLocalAddress()
                    && !ip.isLoopbackAddress()
                    && !ip.getHostAddress().contains(CharacterConstants.COLON)) {
                    // 内网IP
                    localIp = ip.getHostAddress();
                }
            }
        }

        if (netIp != null && !"".equals(netIp)) {
            return netIp;
        } else {
            return localIp;
        }
    }


    /**
     * 获取完整的异常栈信息
     */
    public static String getTrace(Throwable t) {
        StringWriter stringWriter = new StringWriter();
        PrintWriter writer = new PrintWriter(stringWriter);
        t.printStackTrace(writer);
        StringBuffer buffer = stringWriter.getBuffer();
        return buffer.toString();
    }
}
